﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ModelClassesLinqToSql.Domain.Models;
using ModelClassesLinqToSql.Domain.Repositories;
using ModelClassesLinqToSql.Views.Movie;

namespace ModelClassesLinqToSql.Controllers
{
    public class MovieController : Controller
    {
        private IMovieRepository movieRepo;
        private IProductionCompanyRepository compRepo;
        private IEmployeeRepository empRepo;
        private IJobTitleRepository jtRepo;

        private enum ListAction
        {
            None = 0,
            Assign = 1,
            Edit = 2,
            Unassign = 3
        }

        public MovieController()
            : this(new MovieRepository(), new ProductionCompanyRepository(), new EmployeeRepository(), new JobTitleRepository()) 
        {
            
        }

        public MovieController(IMovieRepository movieRepository, IProductionCompanyRepository productionCompanyRepository, IEmployeeRepository employeeRepository, IJobTitleRepository jobTitleRepository)
        {
            this.movieRepo = movieRepository;
            this.compRepo = productionCompanyRepository;
            this.empRepo = employeeRepository;
            this.jtRepo = jobTitleRepository;
        }

        // GET: /Movie/
        public ActionResult Index()
        {
            IList<IndexViewModel> vm = (
                from m in this.movieRepo.GetMoviesAndDirectors()
                group m by m.Movie.Name into g
                select new IndexViewModel() { 
                    Id = g.First().Movie.Id, 
                    Name = g.First().Movie.Name,
                    Director = this.PrintDirectors(g.Select(m => m.Employee)),
                    Released = g.First().Movie.Released
                }
            ).ToList();

            return View(vm);
        }

        private string PrintDirectors(IEnumerable<Employee> directors)
        {
            System.Text.StringBuilder print = new System.Text.StringBuilder();

            foreach (Employee e in directors)
            {
                print.Append(e.FirstName + " " + e.LastName + ", ");
            }

            print.Remove(print.Length - 2, 2);

            return print.ToString();
        }

        // GET: /Movie/Detail/{int}
        [HttpGet]
        public ActionResult Detail(int Id)
        {
            this.SetDetailViewBag();

            Movie movie = this.movieRepo.GetMovie(Id);
            IEnumerable<EmployeeJobTitleComposite> employees = this.movieRepo.GetMovieEmployees(Id);

            DetailViewModel vm = new DetailViewModel()
                {
                    Id = movie.Id,
                    Name = movie.Name,
                    Released = movie.Released,
                    ProductionCompanyId = movie.ProductionCompanyId,
                    Employees = employees
                };

            return View(vm);
        }

        // POST: /Movie/Detail/{DetailViewModel}
        [HttpPost]
        public ActionResult Detail(DetailViewModel vm)
        {
            if (this.ModelState.IsValid)
            {
                Movie movie = this.movieRepo.GetMovie(vm.Id);
                movie.Id = vm.Id;
                movie.Name = vm.Name;
                movie.ProductionCompanyId = vm.ProductionCompanyId;
                movie.Released = vm.Released;

                //parse change list and make changes to MovieEmployeeJobTitle entity
                string changeList = this.Request.Form["EmployeeChangeList"];

                if (changeList.Length > 0)
                {
                    string[] coms = changeList.Split(',');
                    string[] data = null;
                    int eIndex = 0;
                    int jtIndex = 1;
                    int aIndex = 2;
                    MovieEmployeeJobTitle ejt = null;

                    foreach (string c in coms)
                    {
                        data = c.Split('-');

                        if (int.Parse(data[aIndex]) == (int)ListAction.Assign)
                        {
                            //setup insert operation
                            ejt = new MovieEmployeeJobTitle()
                                {
                                    MovieId = vm.Id,
                                    EmployeeId = int.Parse(data[eIndex]),
                                    JobTitleId = int.Parse(data[jtIndex])
                                };

                            this.movieRepo.AssignMovieEmployee(ejt);
                        }
                        else if (int.Parse(data[2]) == (int)ListAction.Unassign)
                        {
                            //setup delete operation
                            ejt = new MovieEmployeeJobTitle()
                            {
                                MovieId = vm.Id,
                                EmployeeId = int.Parse(data[eIndex]),
                                JobTitleId = int.Parse(data[jtIndex])
                            };

                            this.movieRepo.UnassignMovieEmployee(ejt);
                        }
                    }
                }

                this.movieRepo.SaveMovie();

                return this.RedirectToAction("Index");
            }
            else
            {
                this.SetDetailViewBag();

                return View(vm);
            }
        }

        private void SetDetailViewBag()
        {
            this.ViewBag.ProductionCompanies = Domain.Cache.GetProductionCompanies();
            this.ViewBag.Employees = Domain.Cache.GetEmployees();
            this.ViewBag.JobTitles = Domain.Cache.GetJobTitles();
        }

        // GET: /Movie/Dialog/{int}
        [HttpGet]
        public JsonResult Dialog(int Id)
        {
            IEnumerable<Employee> employees = Domain.Cache.GetEmployees();
            IEnumerable<JobTitle> jobTitles = Domain.Cache.GetJobTitles();

            var result = new { employees = employees, jobTitles = jobTitles };

            return Json(result, JsonRequestBehavior.AllowGet);
        }
    }
}
